# -*- coding: utf-8 -*
# 游戏控制器
# 游戏采用事件驱动机制 驱动函数：GameOptAction
# 静态类，里面全是静态方法，相当于一个单例
#!/usr/bin/python3


import sys
import os
sys.path.append(os.getcwd() + "\\2048")

from Core.Data import GameData
from Core.Data import GameDataHelp
from Core.Controller import SortHandle
from Core.Controller import GameState
from Core.Controller.OperationController import OperationController

# from Core.Data import GameDataHelp



class GameController:
    
    __display_func = None
    __display_death_func = None

    # 初始化游戏
    @staticmethod
    def InitGame():
        print(GameState)
        # 设置游戏状态
        # 清除游戏数据
        # 生成随机生成2048的基础增量
        # 刷新分数
        # 显示
        global __inited
        global __display_func
        global __display_death_func
        __display_func = None
        ____display_death_func = None
        GameState.GameState.In()
        GameController.__ClearData()
        GameController.__AddRomdomDataToGameData()
        GameController.__ClaculateResult()
        GameController.Display()
        


    # 退出游戏
    @staticmethod
    def QuitGame():
        GameState.GameState.Out()
        GameController.Display()

    # 退出应用
    @staticmethod
    def QuitApplication():
        return

    # 用户操作接口
    # opt_action 是一个 Operation(Enum) 枚举类型
    @staticmethod
    def GameOptAction(opt_action):
        # 查看游戏是否死亡
        if GameController.CheckGameIsDied():
            print("Game Is Over")
            return
        # 进行操作
        # 进行排序     
        dirc = OperationController.Opt(opt_action)
        data_key = OperationController.GetSelectionDataKey()
        call_back_key = OperationController.GetSelectionCallBackKey()
        
        print("GameController.GameOptAction()" , dirc)

        sorted_data = SortHandle.SortHandle.Sort(dirc[data_key],opt_action)
        new_game_data = dirc[call_back_key](sorted_data)
        GameData.GameData.SetGameData(new_game_data)

        # 生成数据  
        GameController.__AddRomdomDataToGameData()

        # 计算最高得分
        # 显示
        GameController.__ClaculateResult()
        GameController.Display()

        # 查看游戏是否死亡
        # 如果死亡则进行死亡操作 
        if GameController.CheckGameIsDied():
            GameController.__SetGameDeath()
            GameState.GameState.Out()
            GameController.Display()
        return

    # 清除数据
    @staticmethod
    def __ClearData():
        print("GameController.__ClearData():  GameController")
        GameData.GameData.Clear()
        return

    # 调用随机数据生成器生成数据
    @staticmethod
    def __AddRomdomDataToGameData():
        GameDataHelp.GameDataHelp.AddRomdomDataToGameData()
        return


    # 调用游戏检测器检测游戏是否还能继续
    # 死亡规则：1.不能移动，2.不能合并 两个条件都满足则表示死亡
    @staticmethod
    def CheckGameIsDied():
        if GameState.GameState.GetState() == GameState.StateEnum.Death:
            return True

        if SortHandle.SortHandle.CheckCanSort():
            return False

        if GameDataHelp.GameDataHelp.CheckHaveEmpySpace():
            return False
        
        return True
    
    @staticmethod
    def __SetGameDeath():
        GameState.GameState.Out()
        global __display_death_func
        __display_death_func()

    # 调用分数计数器
    @staticmethod
    def __ClaculateResult():
        data = GameData.GameData.GetGameData()
        if type(data) is not tuple and type(data) is not list:
            print("error    type(data) != \"tuple\"  ")
            return None

        list1 = []
        for list_item in data:
            list1.append(max(list_item))
        GameData.GameData.SetResult(max(list1))
        return

    # 显示
    @staticmethod
    def Display():
        global __display_func
        if __display_func != None:
            __display_func()
        return

    @staticmethod
    def SetDisplayFunc(dispaly_func,display_death_func):
        global __display_func
        global __display_death_func

        if dispaly_func != None:
            __display_func = dispaly_func

        if display_death_func != None:
            __display_death_func = display_death_func
        
        #GameController.Display()

GameController.InitGame()
#GameController.Display()